var BusinessOrderMaterialModel = function (material) {
  BaseModel.call(this);

  var self = this;
  var fn = {
    initData: function (material) {
      var fields = ['lineNo', 'materialCode', 'materialColor', 'materialColorDescription', 'materialFactory', 'materialModel',
        'materialProviderName', 'materialType', 'materialName'
      ];
      self.setDataFromObj(material, fields);
    }
  };

  fn.initData(material);
};

var OrderDataModel = function (form, data) {
  BaseModel.call(this);

  var self = this;
  var fn = {
    initData: function (form, data) {
      self.id = SysUtil.getId();
      self.businessOrder = form;
      if (data === undefined) {
        self.lineNo = undefined;
        self.picUrl = '';
        self.unitPrice = undefined;
        self.orderTotal = undefined;
        self.customerColor = '';
        self.customerColorDescription = '';

        self.setGlassesMaterialObj(form.glassesMaterialList);
        self.setDeliveryDateList(form.deliveryDateCount);
        return;
      };
      this.setOrderData(data);
    },

    setOrderData: function (data) {
      var lineNo = data.lineNo;
      self.lineNo = lineNo;
      self.picUrl = '';
      self.unitPrice = undefined;
      self.orderTotal = undefined;
      self.customerColor = '';
      self.customerColorDescription = '';

      var materialList = data.materialList;
      for (var i = 0; i < materialList.length; i++) {
        var material = materialList[i];
        var materialCode = material.materialCode;
        if (materialCode === null) {
          this.setOrderInfo(material);
        }
      }

      self.glassesObj = {};
      self.deliveryDateList = [];

      var sumPrice = self.unitPrice * self.orderTotal;
      sumPrice = _.round(sumPrice, 4);
      self.materialSumPrice = sumPrice;
    },

    setOrderInfo: function (material) {
      var orderInfoConfig = OrderDataModel.orderInfoConfig;
      var materialType = material.materialType;
      var field = orderInfoConfig[materialType];
      if (field === undefined) {
        return;
      }
      var value = material.materialModel;
      if (['unitPrice', 'orderTotal'].indexOf(field) !== -1) {
        value = Number(value);
      }
      self[field] = value;
    },

    getWasteCount: function (wasteRateList, orderTotal) {
      var wasteRate = _.find(wasteRateList, function (obj) {
        return orderTotal >= obj.orderTotalStart && orderTotal <= obj.orderTotalEnd;
      });
      if (wasteRate === undefined) {
        return null;
      }

      var wasteTotal = wasteRate.wasteTotal;
      if (SysUtil.isEmpty(wasteTotal) || wasteTotal === 0) {
        wasteTotal = orderTotal * wasteRate.wasteRate;
      }
      return wasteTotal;
    }
  };

  this.setGlassesMaterialObj = function (glassesMaterialList, glassesData) {
    var glassesObj = {};
    if (glassesData !== undefined) {
      glassesData = _.groupBy(glassesData, 'materialCode');
    }
    for (var i = 0; i < glassesMaterialList.length; i++) {
      var glassesMaterial = glassesMaterialList[i];
      var materialCode = glassesMaterial.materialCode;
      var value = undefined;
      if (glassesData !== undefined) {
        var obj = glassesData[materialCode];
        if (obj !== undefined) {
          value = obj[0].orderTotal;
          value = Number(value);
        }
      }
      glassesObj[materialCode] = value;
    }
    self.glassesObj = glassesObj;
  };

  this.setDeliveryDateList = function (deliveryDateCount, deliveryDateList) {
    var deliveryDates = [];
    for (var i = 0; i < deliveryDateCount; i++) {
      var deliveryDate;
      var obj = deliveryDateList === undefined ? undefined : deliveryDateList[i];
      if (obj === undefined) {
        deliveryDate = {
          date: null,
          count: undefined
        };
      } else {
        var date = obj.dhDate;
        var count = obj.dhTotal;
        count = Number(count);
        deliveryDate = {
          date: moment(date).valueOf(),
          count: count
        };
      }
      deliveryDates.push(deliveryDate);
    }
    deliveryDates = _.orderBy(deliveryDates, [function (obj) {
      var date = obj.date;
      if (date === null) {
        return Infinity;
      }
      return date;
    }], ['asc']);
    self.deliveryDateList = deliveryDates;
  };

  this.getMaterialInfoData = function (materialType, field) {
    var lineNo = this.lineNo;
    if (SysUtil.isEmpty(lineNo)) {
      return '';
    }
    var businessOrder = this.businessOrder;
    var materialData = businessOrder.materialData;
    var materialObj = _.get(materialData, `${lineNo}.${materialType}`);
    if (SysUtil.isEmpty(materialObj)) {
      return '';
    }
    return materialObj[field];
  };

  this.addGlassesData = function (materialList) {
    var glassesObj = this.glassesObj;
    for (var i = 0; i < materialList.length; i++) {
      var material = materialList[i];
      glassesObj[material.materialCode] = undefined;
    }
  };

  this.delGlassesData = function (materialCode) {
    var glassesObj = this.glassesObj;
    delete glassesObj[materialCode];
  };

  this.getTotalGlassesCount = function () {
    var glassesObj = this.glassesObj;
    var count = undefined;
    for (var materialCode in glassesObj) {
      var value = glassesObj[materialCode];
      if (value === undefined) {
        continue;
      }
      if (count === undefined) {
        count = value;
      } else {
        count += value;
      }
    }
    return count;
  };

  this.addDeliveryDate = function () {
    this.deliveryDateList.push({
      date: null,
      count: undefined
    });
  };

  this.delDeliveryDate = function (index) {
    var deliveryDateList = this.deliveryDateList;
    deliveryDateList.splice(index, 1);
  };

  this.checkValid = function (materialData) {
    var lineNo = this.lineNo;
    if (lineNo !== undefined && lineNo !== '9999') {
      if (materialData[lineNo] === undefined) {
        return 'noMaterial';
      }
    }

    if (this.unitPrice === undefined) {
      return 'unitPrice';
    }

    var deliveryDateList = this.deliveryDateList;
    var totalCount = undefined;
    for (var i = 0; i < deliveryDateList.length; i++) {
      var obj = deliveryDateList[i];
      var date = obj.date;
      var count = obj.count;
      if (!SysUtil.isEmpty(date) || !SysUtil.isEmpty(count)) {
        if (SysUtil.isEmpty(date)) {
          return 'deliveryDate';
        }
        if (SysUtil.isEmpty(count)) {
          return 'deliveryCount';
        }
        if (totalCount === undefined) {
          totalCount = count;
        } else {
          totalCount += count;
        }
      }
    }

    if (this.orderTotal === undefined) {
      return 'orderTotal';
    }

    if (totalCount !== undefined && totalCount !== this.orderTotal) {
      return 'totalCount!==orderTotal';
    }

    return '';
  };

  this.getObject = function (wasteRateList) {
    var orderTotal = this.orderTotal;
    var unitPrice = this.unitPrice;
    var sumPrice = unitPrice * orderTotal;
    var list = [{
      label: '单价',
      value: unitPrice
    }, {
      label: '订单数',
      value: orderTotal
    }, {
      label: '金额',
      value: sumPrice
    }, {
      label: '客户色号',
      value: this.customerColor
    }, {
      label: '客户颜色描述',
      value: this.customerColorDescription
    }, {
      label: '图片',
      value: this.picUrl
    }];
    var materialList = [];
    var lineNo = this.lineNo;
    if (lineNo === undefined) {
      lineNo = 9999;
    }
    for (var i = 0; i < list.length; i++) {
      var obj = list[i];
      var value = obj.value;
      if (SysUtil.isEmpty(value)) {
        continue;
      }
      materialList.push({
        lineNo: lineNo,
        materialType: obj.label,
        materialModel: value,
        materialFactory: '3'
      });
    }

    //老花镜
    var businessOrder = this.businessOrder;
    var bomOrder = businessOrder.bomOrder;
    var difficultLevel = bomOrder.difficultLevel;
    var glassesMaterialList = businessOrder.glassesMaterialList;
    var glassesObj = this.glassesObj;
    var glassesList = [];
    for (var i = 0; i < glassesMaterialList.length; i++) {
      var material = glassesMaterialList[i];
      var glassesOrderTotal = glassesObj[material.materialCode];
      if (glassesOrderTotal === undefined) {
        continue;
      }

      var materialType = material.materialType;
      var glassesWasteCount = fn.getWasteCount(wasteRateList, glassesOrderTotal);
      if (glassesWasteCount === null) {
        return `老花镜${materialType}的订单数没有对应的损耗数据`;
      }
      var glassesFeedTotal = glassesWasteCount * difficultLevel + glassesOrderTotal;
      material = _.cloneDeep(material);
      material.lineNo = lineNo;
      material.orderTotal = glassesOrderTotal;
      material.feedTotal = glassesFeedTotal;
      glassesList.push(material);
    }

    //交期
    var deliveryDateList = this.deliveryDateList;
    var deliveryDates = [];
    for (var i = 0; i < deliveryDateList.length; i++) {
      var obj = deliveryDateList[i];
      var date = obj.date;
      if (date === null) {
        continue;
      }
      deliveryDates.push({
        lineNo: lineNo,
        DhDate: moment(date).format('YYYY-MM-DD'),
        DhTotal: obj.count
      });
    }

    return {
      materialList: materialList,
      glassesList: glassesList,
      deliveryDateList: deliveryDates
    };
  };

  this.setCheckUpdate = function (beforeOrder) {
    if (beforeOrder === undefined) {
      this.updateStatusObj = true;
      return;
    }

    var fields = ['customerColor', 'customerColorDescription', 'unitPrice', 'orderTotal', 'materialSumPrice', 'picUrl'];
    var updateStatusObj = {};
    for (var i = 0; i < fields.length; i++) {
      var field = fields[i];
      var value = this[field];
      var beforeValue = beforeOrder[field];
      updateStatusObj[field] = value !== beforeValue;
    }

    var glassesObj = this.glassesObj;
    var beforeGlassesObj = beforeOrder.glassesObj;
    var glassesStatusObj = {};
    for (var materialCode in glassesObj) {
      var value = glassesObj[materialCode];
      var beforeValue = beforeGlassesObj[materialCode];
      glassesStatusObj[materialCode] = value !== beforeValue;
    }
    updateStatusObj.glassesObj = glassesStatusObj;

    var deliveryDateList = this.deliveryDateList;
    var beforeDeliveryDateList = beforeOrder.deliveryDateList;
    var deliveryDateStatusList = [];
    for (var i = 0; i < deliveryDateList.length; i++) {
      var obj = deliveryDateList[i];
      var beforeObj = beforeDeliveryDateList[i];
      if (beforeObj === undefined) {
        beforeObj = {
          date: null,
          count: undefined
        };
      }
      var date = obj.date;
      var beforeDate = beforeObj.date;
      var dateStatus;
      if (date === null || beforeDate === null) {
        dateStatus = date !== beforeDate;
      } else {
        dateStatus = !moment(date).isSame(moment(beforeDate), 'day');
      }
      deliveryDateStatusList.push({
        deliveryDate: dateStatus,
        deliveryCount: obj.count !== beforeObj.count
      });
    }
    updateStatusObj.deliveryDateList = deliveryDateStatusList;

    this.updateStatusObj = updateStatusObj;
  };

  this.checkUpdate = function (columnKey) {
    var updateStatusObj = this.updateStatusObj;
    if (updateStatusObj === undefined) {
      return false;
    }

    if (updateStatusObj === true) {
      return true;
    }

    if (columnKey.indexOf('_') === -1) {
      return updateStatusObj[columnKey];
    }

    var arr = columnKey.split('_');
    var field = arr[0];
    var materialFields = ['materialName', 'materialModel', 'materialProviderName', 'materialColor', 'materialColorDescription'];
    if (materialFields.indexOf(field) !== -1) {
      return false;
    }

    if (field === 'glasses') {
      var materialCode = arr[1];
      var glassesObj = updateStatusObj.glassesObj;
      return glassesObj[materialCode];
    }

    var deliveryDateFields = ['deliveryDate', 'deliveryCount'];
    if (deliveryDateFields.indexOf(field) !== -1) {
      var count = arr[1];
      count = Number(count);
      var index = count - 1;
      var deliveryDateList = updateStatusObj.deliveryDateList;
      var deliveryDate = deliveryDateList[index];
      return deliveryDate[field];
    }
    return false;
  };

  fn.initData(form, data);
};
OrderDataModel.orderInfoConfig = {
  "单价": "unitPrice",
  "订单数": "orderTotal",
  "客户色号": "customerColor",
  "客户颜色描述": "customerColorDescription",
  "图片": "picUrl"
};
OrderDataModel.getMaterialInfo = function (obj) {
  var fields = ['materialCode', 'materialType', 'materialFactory', 'materialName', 'materialProviderName', 'materialColor',
    'materialColorDescription', 'materialModel'
  ];
  var material = {};
  for (var i = 0; i < fields.length; i++) {
    var field = fields[i];
    material[field] = obj[field];
  }
  return material;
};

var BusinessOrderFormModel = function (businessOrder, orderList) {
  BaseModel.call(this);

  var self = this;
  var fn = {
    initData: function (businessOrder, orderList) {
      if (businessOrder === undefined) {
        self.orderNo = '';
        self.bomOrder = '';
        self.orderType = '';
        self.deliveryTime = null;
        self.picUrl = '';
        self.custmer = '';
        self.custmerVersionNo = '';
        self.custmerOrderNo = '';
        self.deliveryDateCount = 0;
        self.glassesMaterialList = [];
        self.materialData = {};
        self.orderDataList = [];
        self.canSave = true;
        self.orderRemark = '';
        return;
      }

      this.setOrderData(businessOrder, orderList);
      self.canSave = true;
      self.setOldData(['orderNo']);
    },

    setOrderData: function (businessOrder, orderList) {
      var masterData = businessOrder.titleBean;
      self.id = masterData.id;
      self.orderNo = masterData.orderNo;
      self.orderType = masterData.orderType;
      self.picUrl = masterData.picUrl;
      self.custmer = masterData.custmer;
      self.custmerVersionNo = masterData.custmerVersionNo;
      self.custmerOrderNo = masterData.custmerOrderNo;

      var orderRemark = masterData.orderRemark;
      if (SysUtil.isEmpty(orderRemark)) {
        orderRemark = '';
      }
      self.orderRemark = masterData.orderRemark;

      var factoryNo = masterData.factoryNo;
      var bomOrder = _.find(orderList, {
        factoryNo: factoryNo
      });
      if (bomOrder === undefined) {
        bomOrder = '';
      }
      self.bomOrder = bomOrder;

      var deliveryTime = masterData.deliveryTime;
      self.deliveryTime = moment(deliveryTime).valueOf();
      self.serialNo = masterData.serialNo;
      self.applyId = masterData.applyId;

      var orderDataList = [];
      var materialList = businessOrder.materialList;
      var glassesMaterialList = businessOrder.glassMaterialBeans;
      var deliveryDateList = businessOrder.dhTotalDates;
      var materialGroup = _.groupBy(materialList, 'lineNo');
      var glassesMaterialGroup = _.groupBy(glassesMaterialList, 'lineNo');
      var deliveryDateGroup = _.groupBy(deliveryDateList, 'lineNo');
      var deliveryDateCount = 0;
      var glassesMaterialObj = {};
      for (var lineNo in materialGroup) {
        var order = new OrderDataModel(self, {
          lineNo: lineNo,
          materialList: materialGroup[lineNo]
        });
        orderDataList.push(order);

        var glassesMaterialList = glassesMaterialGroup[lineNo];
        if (glassesMaterialList === undefined) {
          glassesMaterialList = [];
        }
        for (var i = 0; i < glassesMaterialList.length; i++) {
          var glassMaterial = glassesMaterialList[i];
          var materialCode = glassMaterial.materialCode;
          if (glassesMaterialObj[materialCode] === undefined) {
            glassesMaterialObj[materialCode] = OrderDataModel.getMaterialInfo(glassMaterial);
          }
        }

        var deliveryDateList = deliveryDateGroup[lineNo];
        if (deliveryDateList === undefined) {
          deliveryDateList = [];
        }
        var count = deliveryDateList.length;
        if (deliveryDateCount < count) {
          deliveryDateCount = count;
        }
      }

      var glassesMaterialList = _.values(glassesMaterialObj);
      self.glassesMaterialList = glassesMaterialList;
      self.deliveryDateCount = deliveryDateCount;

      var sumPrice = 0;
      for (var i = 0; i < orderDataList.length; i++) {
        var order = orderDataList[i];
        var lineNo = order.lineNo;
        var glassesData = glassesMaterialGroup[lineNo];
        order.setGlassesMaterialObj(glassesMaterialList, glassesData);
        var deliveryDateList = deliveryDateGroup[lineNo];
        order.setDeliveryDateList(deliveryDateCount, deliveryDateList);
        sumPrice += order.unitPrice * order.orderTotal;
      }

      self.orderDataList = orderDataList;
      self.orderSumPrice = _.round(sumPrice, 4);
    }
  };

  this.resetMaterialData = function (materialList) {
    var materialGroup = _.groupBy(materialList, 'lineNo');
    var materialData = {};
    var materialBomList = [];
    for (var lineNo in materialGroup) {
      var no = Number(lineNo);
      if (no >= 100) {
        continue;
      }

      var materials = materialGroup[lineNo];
      if (no === -1) {
        for (var i = 0; i < materials.length; i++) {
          var material = materials[i];
          var materialFactory = material.materialFactory;
          if (materialFactory !== '3') {
            materialBomList.push(material);
          }
        }
        continue;
      }

      materialDataObj = {};
      for (var i = 0; i < materials.length; i++) {
        var material = materials[i];
        material = new BusinessOrderMaterialModel(material);
        materialDataObj[material.materialType] = material;
      }
      materialData[lineNo] = materialDataObj;
    }
    this.materialData = materialData;
    this.materialBomList = materialBomList;
  };

  this.addOrder = function () {
    var order = new OrderDataModel(this);
    this.orderDataList.push(order);
  };

  this.deleteOrder = function (order) {
    var orderDataList = this.orderDataList;
    var index = _.findIndex(orderDataList, {
      id: order.id
    });
    if (index > -1) {
      orderDataList.splice(index, 1);
    }
  };

  this.addGlassesList = function (materialList) {
    materialList = _.map(materialList, function (material) {
      var defaultWarehouse = material.defaultWarehouse;
      if (defaultWarehouse === '原材料仓') {
        defaultWarehouse = '1';
      } else if (defaultWarehouse === '辅料仓') {
        defaultWarehouse = '2';
      }
      return {
        materialCode: material.materialCode,
        materialType: material.materialType,
        materialName: material.materialName,
        materialModel: material.model,
        materialFactory: defaultWarehouse,
        materialProviderName: material.providerName,
        materialColor: material.color,
        materialColorDescription: material.colorDescription
      };
    });

    var orderDataList = this.orderDataList;
    for (var i = 0; i < orderDataList.length; i++) {
      var order = orderDataList[i];
      order.addGlassesData(materialList);
    }

    this.glassesMaterialList.pushArray(materialList);
  };

  this.delGlasses = function (glasses) {
    var materialCode = glasses.materialCode;
    var glassesMaterialList = this.glassesMaterialList;
    var index = _.findIndex(glassesMaterialList, {
      materialCode: materialCode
    });
    if (index === -1) {
      return;
    }

    var orderDataList = this.orderDataList;
    for (var i = 0; i < orderDataList.length; i++) {
      var order = orderDataList[i];
      order.delGlassesData(materialCode);
      var orderTotal = order.getTotalGlassesCount();
      if (orderTotal !== undefined) {
        order.orderTotal = orderTotal;
      }
    }
    glassesMaterialList.splice(index, 1);
  };

  this.addDeliveryDate = function () {
    var orderDataList = this.orderDataList;
    for (var i = 0; i < orderDataList.length; i++) {
      var order = orderDataList[i];
      order.addDeliveryDate();
    }
    this.deliveryDateCount++;
  };

  this.delDeliveryDate = function (index) {
    var orderDataList = this.orderDataList;
    for (var i = 0; i < orderDataList.length; i++) {
      var order = orderDataList[i];
      order.delDeliveryDate(index);
    }
    this.deliveryDateCount--;
  };

  this.checkValid = function () {
    var fields = ['orderNo', 'bomOrder', 'orderType', 'deliveryTime'];
    for (var i = 0; i < fields.length; i++) {
      var field = fields[i];
      var value = this[field];
      if (SysUtil.isEmpty(value)) {
        return field;
      }
    }

    var orderDataList = this.orderDataList;
    var materialData = this.materialData;
    var lineNoList = [];
    var count = 0;
    for (var i = 0; i < orderDataList.length; i++) {
      var order = orderDataList[i];
      var code = order.checkValid(materialData);
      if (code !== '') {
        return {
          index: i,
          code: code
        };
      }

      var lineNo = order.lineNo;
      if (lineNo !== undefined && lineNo !== '9999') {
        lineNoList.push(order.lineNo);
      } else {
        count++;
      }
    }

    if (count > 1) {
      return 'noLineCount>1';
    }

    var list = _.uniq(lineNoList);
    if (lineNoList.length !== list.length) {
      return 'lineNoRepeat';
    }

    return '';
  };

  this.getObject = function (type, wasteRateList, user) {
    var deliveryTime = this.deliveryTime;
    var bomOrder = this.bomOrder;
    var masterData = {
      orderNo: this.orderNo,
      factoryNo: bomOrder.factoryNo,
      custmer: this.custmer,
      custmerVersionNo: this.custmerVersionNo,
      custmerOrderNo: this.custmerOrderNo,
      orderType: this.orderType,
      deliveryTime: moment(deliveryTime).format('YYYY-MM-DD'),
      picUrl: this.picUrl,
      orderRemark: this.orderRemark,
      status: -1
    };

    if (user) {
      masterData.creater = user.userName;
    }

    var id = this.id;
    if (type === 'update' && !SysUtil.isEmpty(id)) {
      masterData.id = id;
      masterData.serialNo = this.serialNo;
    }

    var sumPrice = 0;
    var materialList = [],
      glassesMaterialList = [],
      deliveryDateList = [];
    var orderDataList = this.orderDataList;
    for (var i = 0; i < orderDataList.length; i++) {
      var order = orderDataList[i];
      var orderPostData = order.getObject(wasteRateList);

      sumPrice += order.unitPrice * order.orderTotal;
      materialList.pushArray(orderPostData.materialList);
      glassesMaterialList.pushArray(orderPostData.glassesList);
      deliveryDateList.pushArray(orderPostData.deliveryDateList);
    }
    masterData.sumPrice = _.round(sumPrice, 4);

    return {
      titleBean: masterData,
      materialList: materialList,
      glassMaterialBeans: glassesMaterialList,
      dhTotalDates: deliveryDateList
    };
  };

  this.setCheckUpdate = function (beforeData) {
    var fields = ['orderNo', 'orderType', 'orderSumPrice', 'custmer', 'custmerVersionNo', 'custmerOrderNo'];
    var updateStatusObj = {};
    for (var i = 0; i < fields.length; i++) {
      var field = fields[i];
      var value = this[field];
      var beforeValue = beforeData[field];
      updateStatusObj[field] = value !== beforeValue;
    }

    var factoryNo = this.bomOrder.factoryNo;
    var beforeFactoryNo = beforeData.bomOrder.factoryNo;
    updateStatusObj['bomOrder'] = factoryNo !== beforeFactoryNo;

    var deliveryTime = this.deliveryTime;
    updateStatusObj['deliveryTime'] = !moment(deliveryTime).isSame(moment(beforeData.deliveryTime), 'day');

    var orderDataList = this.orderDataList;
    var beforeOrderDataList = beforeData.orderDataList;
    for (var i = 0; i < orderDataList.length; i++) {
      var order = orderDataList[i];
      order.setCheckUpdate(beforeOrderDataList[i]);
    }

    this.updateStatusObj = updateStatusObj;
  };

  this.checkUpdate = function (field) {
    var updateStatusObj = this.updateStatusObj;
    if (updateStatusObj === undefined) {
      return false;
    }

    return updateStatusObj[field];
  };

  fn.initData(businessOrder, orderList);
};
BusinessOrderFormModel.tableCol = [{
  id: "materialName",
  label: "物料名称"
}, {
  id: "materialModel",
  label: "物料规格"
}, {
  id: "materialProviderName",
  label: "供应商"
}, {
  id: "materialColor",
  label: "色号"
}, {
  id: "materialColorDescription",
  label: "颜色描述"
}];
